package process2

import (
	"chatOnline/common/message"
	"chatOnline/server/model"
	"chatOnline/server/utils"
	"encoding/json"
	"fmt"
	"net"
)

/*
处理用户相关的请求
登录 注册
*/
type UserProcess struct {
	Conn net.Conn
	// 增加一个字段 表示该Conn 是那个用户的
	UserId int
}

//编写通知所有在线用户的方法
// userID 要通知其他的在线用户，我上线
func (this *UserProcess) NotifyOthersOnlineUser(userId int) {

	// 遍历onlineUsers 然后一个一个的发送 用户状态变化消息
	for id, up := range UserMgrs.GetAllOnlineUser() {
		// 过滤自己
		if id == userId {
			continue
		}

		// 开始通知
		up.NotifyMeOnline(userId)
	}
}

func (this *UserProcess) NotifyMeOnline(userId int) {

	// 组装我们的NotifyUserStatusMesType
	var mes message.Message
	mes.Type = message.NotifyUserStatusMesType
	var notifyUserStatusMes message.NotifyUserStatusMes
	notifyUserStatusMes.UserId = userId
	notifyUserStatusMes.Status = message.UserOnline

	data, err := json.Marshal(notifyUserStatusMes)
	if err != nil {
		fmt.Println("notify json.Marshal err=", err)
		return
	}
	// 序列化后的notfyUserStatusMes 赋值给mes.Data
	mes.Data = string(data)

	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("mes data json.Marshal err=", err)
		return
	}
	//  发送 创建一个Transfer实例
	tf := &utils.Transfer{
		Conn: this.Conn,
	}
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("NotifyMeOnline err=", err)
		return
	}

}

// 编写一个函数serverProcessLogin 函数 专门处理登录请求
func (this *UserProcess) ServerProcessRegister(mes *message.Message) (err error) {
	// 核心代码 ...
	// 1.先从mes 中取出mes.Data 并直接反序列会成LoginMes
	var registerMes message.RegisterMes
	err = json.Unmarshal([]byte(mes.Data), &registerMes)
	if err != nil {
		fmt.Println("json.Unmarshal faill err=", err)
		return
	}
	// 先声明一个resMes
	var resMes message.Message
	resMes.Type = message.RegisterMesType
	// 再声明一个LoginResMessage
	var registerResMes message.RegisterResMes

	err = model.MyUserDao.Register(&registerMes.User)

	if err != nil {
		if err == model.ERROR_USER_EXISTS {
			registerResMes.Code = 505
			registerResMes.Error = model.ERROR_USER_EXISTS.Error()
		} else {
			registerResMes.Code = 506
			registerResMes.Error = "注册发生未知错误.."
		}

		// 这里我们先测试成功，然后可以根据返回具体错误信息
	} else {
		registerResMes.Code = 200
		fmt.Println(registerMes.User, "注册成功")

	}

	// 3 将loginResMes 序列化
	data, err := json.Marshal(registerResMes)
	if err != nil {
		fmt.Println("json.Marshal fail", err)
		return
	}

	// 4. 将data 赋值给resMes
	resMes.Data = string(data)
	//5. 对resMes 进行序列化，准备发送
	data, err = json.Marshal(resMes)
	if err != nil {
		fmt.Println("json.Marshal fail", err)
		return
	}
	// 6. 发送data,我们将其封装到writePkg函数
	// 因为使用了分层模式（mvc) 我们先创建一个Transfer 实例 然后读取
	tf := &utils.Transfer{
		Conn: this.Conn,
	}

	err = tf.WritePkg(data)
	fmt.Println("write data=", string(data))
	return
}

// 编写一个函数serverProcessLogin 函数 专门处理登录请求
func (this *UserProcess) ServerProcessLogin(mes *message.Message) (err error) {
	// 核心代码 ...
	// 1.先从mes 中取出mes.Data 并直接反序列会成LoginMes
	var loginMes message.LoginMes
	json.Unmarshal([]byte(mes.Data), &loginMes)
	if err != nil {
		fmt.Println("json.Unmarshal faill err=", err)
		return
	}
	// 先声明一个resMes
	var resMes message.Message
	resMes.Type = message.LoginResMesType
	// 再声明一个LoginResMessage
	var loginResMes message.LoginResMes

	user, err := model.MyUserDao.Login(loginMes.UserId, loginMes.UserPwd)

	if err != nil {
		if err == model.ERROR_USER_NOTEXISTS {
			loginResMes.Code = 500
			loginResMes.Error = err.Error()
		} else if err == model.ERROR_USER_PWD {
			loginResMes.Code = 403
			loginResMes.Error = err.Error()
		} else {
			loginResMes.Code = 505
			loginResMes.Error = "服务器内部错误.."
		}

		// 这里我们先测试成功，然后可以根据返回具体错误信息
	} else {
		loginResMes.Code = 200
		// 将当前用户信息放入userMgr
		this.UserId = loginMes.UserId
		UserMgrs.AddOnlineUser(this)
		this.NotifyOthersOnlineUser(loginMes.UserId)
		// 将当前在线用户的id 放入loginResMsg.UserIds
		for id, _ := range UserMgrs.onlineUsers {
			loginResMes.UserIds = append(loginResMes.UserIds, id)
		}
		fmt.Println(user, "登录成功")

	}

	//// 如果id = 100,密码=123456 认为合法 否则不合法
	//if loginMes.UserId == 123 && loginMes.UserPwd =="123" {
	//	// 合法
	//	loginResMes.Code=200
	//}else {
	//	// 不合法
	//	loginResMes.Code=500 // 假定500 状态码 表示该用户不存在
	//	loginResMes.Error="该用户不存在,请先注册再使用"
	//}

	// 3 将loginResMes 序列化
	data, err := json.Marshal(loginResMes)
	if err != nil {
		fmt.Println("json.Marshal fail", err)
		return
	}

	// 4. 将data 赋值给resMes
	resMes.Data = string(data)
	//5. 对resMes 进行序列化，准备发送
	data, err = json.Marshal(resMes)
	if err != nil {
		fmt.Println("json.Marshal fail", err)
		return
	}
	// 6. 发送data,我们将其封装到writePkg函数
	// 因为使用了分层模式（mvc) 我们先创建一个Transfer 实例 然后读取
	tf := &utils.Transfer{
		Conn: this.Conn,
	}

	err = tf.WritePkg(data)
	fmt.Println("write data=", string(data))
	return
}
